<template>
<!-- sku代表该商品可选规格的任意组合，他是库存单位的唯一标识。 -->
  <div class="goods-sku" v-for="item in goods.specs" :key="item.id">
    <dl>
      <dt>{{item.name}}</dt>
      <dd>
         <template v-for="val in item.values" :key="val.name">
          <img :class="{selected:val.selected,disabled:val.disabled}" @click="clickSpecs(item,val)" v-if="val.picture" :src="val.picture" :title="val.name">
          <span :class="{selected:val.selected,disabled:val.disabled}" @click="clickSpecs(item,val)" v-else>{{val.name}}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>
<script>
import powerSet from '@/vendor/power-set'
import { watch } from 'vue'
// import Message from '@/components/library/Message'
// 获取可选集合
const spliter = '★'
const pathMap = {}
const getPathMap = (skus) => {
  // console.log(skus)
  // const temp = []// 测试用的数组
  // 获取到有库存的可选规格
  skus.forEach(item => {
    // 如果还有库存 那就是可以选择
    if (item.inventory) {
      // 获取到有库存情况下的可选规格
      const valueNames = item.specs.map(v => v.valueName)
      // console.log(valueNames)
      // 得到item属性值数组的子集
      const powerSetValues = powerSet(valueNames)
      // console.log(powerSetValues)
      // 设置给路径字典对象
      powerSetValues.forEach(item2 => {
        // 由于可选自己是数组，后续判断不方便，所以把数组字符串化
        const key = item2.join(spliter)
        // console.log(key)
        if (pathMap[key]) {
          // 已经有key往数组追加
          pathMap[key].push(item.id)
        } else {
          // 没有key设置一个数组
          pathMap[key] = [item.id]
        }
      })
      // temp.push(powerSetValues)
    }
  })
  // console.log('测试用的数组', temp)
  console.log('字典', pathMap)
  return pathMap
}
// 获取用户选中的字段
const getSelectedArr = (specs) => {
  const arr = []
  specs.forEach((spec, index) => {
    // 每个字段上都有属于自己的 selected 选中就是为true
    const obj = spec.values.find(item => item.selected === true)
    // console.log(obj)//拿到的是一个对象 赋值给arr
    arr.push(obj ? obj.name : undefined)
  })
  // console.log(arr)
  return arr
}

// 更新按钮禁用状态
const updateDisabledStatus = (specs, pathMap) => {
  // console.log(specs, pathMap)
  // 遍历所有的规格组件
  specs.forEach((spec, i) => {
    // console.log(spec, i)
    // 获取用户选中的规则
    const selectedArr = getSelectedArr(specs)
    // console.log(selectedArr)
    spec.values.forEach(val => {
      if (val.name === selectedArr[i]) return false
      // 未选中的替换对应的值
      selectedArr[i] = val.name
      // 过滤掉无效的属性  ,处理成key
      const key = selectedArr.filter(item => item).join(spliter)
      // 设置禁用状态
      val.disabled = !pathMap[key]
    })
  })
}

const initSelectedStatus = (skuId, goods) => {
  console.log(goods)
  const sku = goods.skus.find(item => item.id === skuId)
  if (sku) {
    goods.specs.forEach((spec, index) => {
      const value = sku.specs[index].valueName
      spec.values.forEach(item => {
        item.selected = item.name === value
      })
    })
  }
}
export default {
  name: 'GoodsSku',
  props: {
    goods: {
      type: Object,
      default: () => {}
    },
    skuId: {
      type: String,
      default: ''
    }
  },
  emits: ['change'],
  setup (props, { emit }) {
    // 选中的效果
    const clickSpecs = (item, val) => {
    //   console.log(item, val)
      if (val.disabled) return
      // 如果有这个属性就设置为false
      if (val.selected) {
        val.selected = false
      } else {
        //   排他思想
        item.values.forEach(bv => { bv.selected = false })
        val.selected = true
      }
      // 更新组件的高亮
      updateDisabledStatus(props.goods.specs, pathMap)
      // 获取到当前选中的规格：每个规格上有 selected 字段
      const arr = getSelectedArr(props.goods.specs)
      console.log('当前用户选中的字段为', arr)
      // 只要有一个为undefined
      if (arr.includes(undefined)) {
        console.log('没有选完整的规格')
        emit('change', {})
        // Message({ type: 'warn', message: '没有选完整的规格' })
      } else {
        const key = arr.join(spliter)
        console.log(key)
        // 拿到skuid
        const [skuid] = pathMap[key]
        // 根据skuid查找商品信息(价格,旧价格,库存,规格文本)
        const obj = props.goods.skus.find(item => item.id === skuid)
        console.log(obj)
        const data = {
          skuId: obj.id,
          inventory: obj.inventory,
          oldPrice: obj.oldPrice,
          price: obj.price,
          specsText: obj.specs.map(item => `${item.name}:${item.valueName}`).join(' ')
        }
        console.log(data)
        emit('change', data)
      }
    }
    // 传入skuid默认选中规格按钮
    initSelectedStatus(props.skuId, props.goods)
    getPathMap(props.goods.skus)
    // 更新组件的高亮
    updateDisabledStatus(props.goods.specs, pathMap)
    watch(props, () => {
      // 更新字典
      getPathMap(props.goods.skus)
    }, { immediate: true })
    return { clickSpecs }
  }
}
</script>
<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  margin-bottom: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;

  dl {
    display: flex;
    // padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
